﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Allinpay.Model
{
    /// <summary>
    /// 所有返回结果的基类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public abstract class BaseResponse<T> where T : BaseResultInfo
    {
        public ErrorResponseInfo error_response { get; set; }

        protected abstract T GetResultInfo();

        public CheckResultResponseInfo<T> CheckResultResponse(BaseParamInfo request)
        {
            var res = new CheckResultResponseInfo<T>();
            BaseResultInfo resultInfo = GetResultInfo();
            var baseResult = error_response ?? resultInfo;

            if (baseResult == null)
            {
                res.IsSuccess = false;
                res.ShowUserMsg = "系统异常！";
                res.LogMsg = "BaseResultInfo为null";
                AllinpayLib.WriteLog(LogTagType.CheckRequetsResult, res.LogMsg);
                return res;
            }

            //if (!CheckRequestResultTimeout(request))
            //{
            //    res.ShowUserMsg = "系统异常！";
            //    res.LogMsg = "{0}\nresult:{1}".FormatWith("支付接口返回超时！", error_response.ToJson());
            //    res.IsSuccess = false;
            //    return res;
            //}

            if (error_response != null)
            {
                res.IsSuccess = false;
                res.ShowUserMsg = error_response.sub_msg ?? error_response.msg;
                res.LogMsg = "code:{0},msg:{1},sub_code:{2},sub_msg:{3}".FormatWith(
                    error_response.code.ToString(), error_response.msg, error_response.sub_code, error_response.sub_msg);
                AllinpayLib.WriteLog(LogTagType.CheckRequetsResult, res.LogMsg);
                return res;
            }

            if (!CheckRequestResultSign(request, baseResult))
            {
                res.ShowUserMsg = "系统异常！";
                res.LogMsg = "签名错误！";
                AllinpayLib.WriteLog(LogTagType.CheckRequetsResult, res.LogMsg);
                res.IsSuccess = false;
                return res;
            }

            AllinpayLib.WriteLog(LogTagType.CheckRequetsResult, "验证成功！");
            res.IsSuccess = true;
            res.ResultInfo = GetResultInfo();
            return res;
        }

        protected virtual bool CheckRequestResultTimeout(BaseParamInfo request)
        {
            //var timeout = AllinpayLib.TimeoutSeconds;
            //if (timeout > 0)
            //{
            //    var t = Math.Abs(request.timestamp.ToLong() - res_timestamp.ToLong());
            //    if (t > timeout)
            //    {
            //        return false;
            //    }
            //}
            return true;
        }

        /// <summary>
        /// 检查返回结果的签名
        /// </summary>
        /// <param name="request"></param>
        /// <param name="resultInfo"></param>
        /// <returns></returns>
        protected virtual bool CheckRequestResultSign(BaseParamInfo request, BaseResultInfo resultInfo)
        {
            /*密钥+ “app_key”+value+”method”+value+” order_id”+value+” res_timestamp”+value+”sign_v”+value+” timestamp”+value+”v”+value
+密钥  ,其中 order_id 如查询类交易没有，或为空则不参与原字符串的拼装
            */
            const string fmt = "{0}app_key{1}method{2}{3}res_timestamp{4}sign_v{5}timestamp{6}v{7}{0}";
            string order_id = null;
            var orderParam = request as BaseHandleOrderParamInfo;
            if (orderParam != null)
            {
                order_id = "order_id" + orderParam.order_id;
            }
            string tmp = fmt.FormatWith(
                AllinpayLib.AppResponseSecret
                , AllinpayLib.AppKey
                , request.method
                , order_id
                , resultInfo.res_timestamp
                , request.sign_v
                , request.timestamp
                , request.v
                );
            AllinpayLib.Log(tmp);
            var sign = tmp.ToMD5(1);
            AllinpayLib.Log(sign);
            AllinpayLib.Log(resultInfo.res_sign);
            return sign == resultInfo.res_sign;
        }
    }
}
